////////////////////////////////////////////////////////////////////////////////
/// @file     slcd.c
/// @author   AE TEAM
/// @brief    THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
////////////////////////////////////////////////////////////////////////////////
/// @attention
///
/// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
/// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
/// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
/// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
/// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
/// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
///
/// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
////////////////////////////////////////////////////////////////////////////////

// Define to prevent recursive inclusion
#define _SLCD_C_

// Files includes
#include "stdio.h"
#include "mm32_device.h"
#include "hal_conf.h"
#include "delay.h"
#include "slcd.h"
#define LSEREADTIMEOUT                  8000
#define LCD_COM_NUMBER      (4)
#define LCD_SEG_NUMBER      (25-3)


////sample
//SLCD_IOConfig_TypeDef SEGorCOM[MAX_SLCD_PIN_NUMBER]={
//  SLCD_IOConfigNone , //SLCD_L0
//  SLCD_IOConfigCOM  , //SLCD_L1
//  SLCD_IOConfigSEG  , //SLCD_L2
//  SLCD_IOConfigSEG  , //SLCD_L3
//  SLCD_IOConfigSEG  , //SLCD_L4
//  SLCD_IOConfigSEG  , //SLCD_L5
//  SLCD_IOConfigSEG  , //SLCD_L6
//  SLCD_IOConfigSEG  , //SLCD_L7
//  SLCD_IOConfigSEG  , //SLCD_L8
//  SLCD_IOConfigSEG  , //SLCD_L9
//  SLCD_IOConfigSEG  , //SLCD_L10
//  SLCD_IOConfigSEG  , //SLCD_L11
//  SLCD_IOConfigSEG  , //SLCD_L12
//  SLCD_IOConfigSEG  , //SLCD_L13
//  SLCD_IOConfigSEG  , //SLCD_L14
//  SLCD_IOConfigSEG  , //SLCD_L15
//  SLCD_IOConfigSEG  , //SLCD_L16
//  SLCD_IOConfigSEG  , //SLCD_L17
//  SLCD_IOConfigSEG  , //SLCD_L18
//  SLCD_IOConfigSEG  , //SLCD_L19
//  SLCD_IOConfigSEG  , //SLCD_L20
//  SLCD_IOConfigSEG  , //SLCD_L21
//  SLCD_IOConfigSEG  , //SLCD_L22
//  SLCD_IOConfigSEG  , //SLCD_L23
//  SLCD_IOConfigSEG  , //SLCD_L24
//  SLCD_IOConfigSEG  , //SLCD_L25
//  SLCD_IOConfigSEG  , //SLCD_L26
//  SLCD_IOConfigSEG  , //SLCD_L27
//  SLCD_IOConfigSEG  , //SLCD_L28
//  SLCD_IOConfigSEG  , //SLCD_L29
//  SLCD_IOConfigSEG  , //SLCD_L30
//  SLCD_IOConfigSEG  , //SLCD_L31
//  SLCD_IOConfigSEG  , //SLCD_L32
//  SLCD_IOConfigSEG  , //SLCD_L33
//  SLCD_IOConfigSEG  , //SLCD_L34
//  SLCD_IOConfigSEG  , //SLCD_L35
//  SLCD_IOConfigSEG  , //SLCD_L36
//  SLCD_IOConfigSEG  , //SLCD_L37
//  SLCD_IOConfigSEG  , //SLCD_L38
//  SLCD_IOConfigSEG  , //SLCD_L39
//  SLCD_IOConfigSEG  , //SLCD_L40
//  SLCD_IOConfigSEG  , //SLCD_L41
//  SLCD_IOConfigSEG  , //SLCD_L42
//  SLCD_IOConfigSEG  , //SLCD_L43
//  SLCD_IOConfigSEG  , //SLCD_L44
//  SLCD_IOConfigSEG  , //SLCD_L45
//  SLCD_IOConfigSEG  , //SLCD_L46
//  SLCD_IOConfigSEG  , //SLCD_L47
//  SLCD_IOConfigSEG  , //SLCD_L48
//  SLCD_IOConfigSEG  , //SLCD_L49
//  SLCD_IOConfigSEG  , //SLCD_L50
//  SLCD_IOConfigSEG  , //SLCD_L51
//  SLCD_IOConfigSEG  , //SLCD_L52
//  SLCD_IOConfigSEG  , //SLCD_L53
//  SLCD_IOConfigSEG  , //SLCD_L54
//  SLCD_IOConfigSEG  , //SLCD_L55
//  SLCD_IOConfigSEG  , //SLCD_L56
//  SLCD_IOConfigSEG  , //SLCD_L57
//  SLCD_IOConfigNone , //SLCD_L58
//  SLCD_IOConfigNone , //SLCD_L59
//  SLCD_IOConfigNone , //SLCD_L60
//  SLCD_IOConfigNone , //SLCD_L61
//  SLCD_IOConfigNone , //SLCD_L62
//  SLCD_IOConfigNone   //SLCD_L63
//};

//sample
SLCD_IOConfig_TypeDef SEGorCOM[MAX_SLCD_PIN_NUMBER] = {
    SLCD_IOConfigCOM,                   //SLCD_L0     PC13 -> COM
    SLCD_IOConfigCOM,                   //SLCD_L1     PD7  -> COM
    SLCD_IOConfigNone,                  //SLCD_L2     PB9  -> NONE
    SLCD_IOConfigSEG,                   //SLCD_L3     PB8  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L4     PC12 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L5     PC11 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L6     PC10 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L7     PA15 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L8     PD3  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L9     PD2  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L10    PA12 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L11    PA11 -> SEG
    SLCD_IOConfigNone,                  //SLCD_L12    PA10 -> NONE
    SLCD_IOConfigNone,                  //SLCD_L13    PA9  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L14    PA8  -> NONE
    SLCD_IOConfigSEG,                   //SLCD_L15    PC9  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L16    PC8  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L17    PC7  -> SEG
    SLCD_IOConfigNone,                  //SLCD_L18    PC6  -> NONE
    SLCD_IOConfigSEG,                   //SLCD_L19    PB15 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L20    PB14 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L21    PB13 -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L22    PB12 -> SEG
    SLCD_IOConfigNone,                  //SLCD_L23    PB11 -> NONE
    SLCD_IOConfigNone,                  //SLCD_L24    PB10 -> NONE
    SLCD_IOConfigNone,                  //SLCD_L25    PB2  -> NONE
    SLCD_IOConfigSEG,                   //SLCD_L26    PB1  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L27    PB0  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L28    PC5  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L29    PC4  -> SEG
    SLCD_IOConfigSEG,                   //SLCD_L30    PA7  -> SEG
    SLCD_IOConfigNone,                  //SLCD_L31    PA6  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L32    PA5  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L33    PA4  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L34    PD5  -> NONE
    SLCD_IOConfigCOM,                   //SLCD_L35    PD4  -> COM
    SLCD_IOConfigNone,                  //SLCD_L36    PA3  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L37    PA2  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L38    PA1  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L39    PA0  -> NONE
    SLCD_IOConfigCOM,                   //SLCD_L40    PC3  -> COM
    SLCD_IOConfigNone,                  //SLCD_L41    PC2  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L42    PC1  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L43    PC0  -> NONE
    SLCD_IOConfigNone,                  //SLCD_L44
    SLCD_IOConfigNone,                  //SLCD_L45
    SLCD_IOConfigNone,                  //SLCD_L46
    SLCD_IOConfigNone,                  //SLCD_L47
    SLCD_IOConfigNone,                  //SLCD_L48
    SLCD_IOConfigNone,                  //SLCD_L49
    SLCD_IOConfigNone,                  //SLCD_L50
    SLCD_IOConfigNone,                  //SLCD_L51
    SLCD_IOConfigNone,                  //SLCD_L52
    SLCD_IOConfigNone,                  //SLCD_L53
    SLCD_IOConfigNone,                  //SLCD_L54
    SLCD_IOConfigNone,                  //SLCD_L55
    SLCD_IOConfigNone,                  //SLCD_L56
    SLCD_IOConfigNone,                  //SLCD_L57
    SLCD_IOConfigSEG,                   //SLCD_L58    PD6  -> SEG
    SLCD_IOConfigNone,                  //SLCD_L59    PB3  -> SLCD_V3
    SLCD_IOConfigNone,                  //SLCD_L60    PB4  -> SLCD_V2
    SLCD_IOConfigNone,                  //SLCD_L61    PB5  -> SLCD_V1
    SLCD_IOConfigNone,                  //SLCD_L62    PB6  -> SLCD_CAP2
    SLCD_IOConfigNone                   //SLCD_L63    PB7  -> SLCD_CAP1
};

//samples
//u8 SCLD_COM_Index[]={
//  0, //COM0 point to SLCD_L0
//  1, //COM1 point to SLCD_L1
//  2, //COM2 point to SLCD_L2
//  3, //COM3 point to SLCD_L3
//  4, //COM4 point to SLCD_L4
//  5, //COM5 point to SLCD_L5
//  6, //COM6 point to SLCD_L6
//  7, //COM7 point to SLCD_L7
//};
//samples

u8 SCLD_COM_Index[COM_INDEX_MAX] = {
    35,                                 //COM0 point to PD4  -> SLCD_L35
    40,                                 //COM1 point to PC3  -> SLCD_L40
    0,                                  //COM2 point to PC13 -> SLCD_L0
    1,                                  //COM3 point to PD7  -> SLCD_L1
    54,                                 //COM4 point to SLCD_L54
    55,                                 //COM5 point to SLCD_L55
    56,                                 //COM6 point to SLCD_L56
    57,                                 //COM7 point to SLCD_L57
};

//Samples
//u8 SCLD_BLINK_Index[COM_INDEX_MAX*BLINK_INDEX_STEP]={
//  1,0,0, //BLINK_Index0 point to COM0 and SEG0
//  1,1,1, //BLINK_Index1 point to COM1 and SEG1
//  1,2,2, //BLINK_Index2 point to COM2 and SEG2
//  1,3,3, //BLINK_Index3 point to COM3 and SEG3
//  1,4,4, //BLINK_Index4 point to COM4 and SEG4
//  1,5,5, //BLINK_Index5 point to COM5 and SEG5
//  1,6,6, //BLINK_Index6 point to COM6 and SEG6
//  1,7,7, //BLINK_Index7 point to COM7 and SEG7
//};
//Samples
u8 SCLD_BLINK_Index[COM_INDEX_MAX * BLINK_INDEX_STEP] = {
    1, 0, 0,                            //BLINK_Index0 point to COM0 and SEG0
    1, 1, 1,                            //BLINK_Index1 point to COM1 and SEG1
    1, 2, 2,                            //BLINK_Index2 point to COM2 and SEG2
    1, 3, 3,                            //BLINK_Index3 point to COM3 and SEG3
    1, 4, 4,                            //BLINK_Index4 point to COM4 and SEG4
    1, 5, 5,                            //BLINK_Index5 point to COM5 and SEG5
    1, 6, 6,                            //BLINK_Index6 point to COM6 and SEG6
    1, 7, 7,                            //BLINK_Index7 point to COM7 and SEG7
};

const LCD_CODING_TypeDef LCD_CODE_Table[38] = {
    {' ', 0x00},
    {'0', 0x3F},
    {'1', 0x06},
    {'2', 0x5B},
    {'3', 0x4F},
    {'4', 0x66},
    {'5', 0x6D},
    {'6', 0x7D},
    {'7', 0x07},
    {'8', 0x7F},
    {'9', 0x6F},
    {'A', 0x77},
    {'b', 0x7C},
    {'c', 0x58},
    {'C', 0x39},
    {'d', 0x5E},
    {'E', 0x79},
    {'F', 0x71},
    {'g', 0x6F},
    {'H', 0x76},
    {'h', 0x74},
    {'i', 0x04},
    {'I', 0x30},
    {'J', 0x1E},
    {'l', 0x30},
    {'L', 0x38},
    {'n', 0x54},
    {'o', 0x5C},
    {'O', 0x3F},
    {'P', 0x73},
    {'q', 0x67},
    {'r', 0x50},
    {'S', 0x6D},
    {'t', 0x78},
    {'u', 0x1C},
    {'U', 0x3E},
    {'y', 0x6E},
    {'-', 0x40},
};
const char LCD_NAME_Table[LCD_COM_NUMBER][LCD_SEG_NUMBER][4] = {
    {"1D ", "DP1", "2D ", "DP2", "3D ", "DP3", "4D ", "C1 ", "C2 ", /*"W5 ", "L1 ",*/ "5F ",  "5A ", "6F ", "6A ", "7F ", "7A ", "S4 ", /*"S5 ",*/ "8F ", "8A ", "9F ", "9A ", "10F", "10A"},
    {"1E ", "1C ", "2E ", "2C ", "3E ", "3C ", "4E ", "4C ", "C3 ", /*"W4 ", "L2 ",*/ "5G ",  "5B ", "6G ", "6B ", "7G ", "7B ", "S3 ", /*"S6 ",*/ "8G ", "8B ", "9G ", "9B ", "10G", "10B"},
    {"1G ", "1B ", "2G ", "2B ", "3G ", "3B ", "4G ", "4B ", "T1 ", /*"W3 ", "L3 ",*/ "5E ",  "5C ", "6E ", "6C ", "7E ", "7C ", "S2 ", /*"S7 ",*/ "8E ", "8C ", "9E ", "9C ", "10E", "10C"},
    {"1F ", "1A ", "2F ", "2A ", "3F ", "3A ", "4F ", "4A ", "W1 ", /*"W2 ", "L4 ",*/ "5D ",  "DP5", "6D ", "DP6", "7D ", "DP7", "S1 ", /*"S8 ",*/ "8D ", "DP8", "9D ", "DP9", "10D", "S9 "},
};
const u32 LCD_SEG_Table[LCD_SEG_NUMBER][2] = {
    {0, SLCD_L3 },   /* PIN1  -> SCH_SLCDL0  -> PB8  -> L3  */
    {0, SLCD_L7 },   /* PIN2  -> SCH_SLCDL1  -> PA15 -> L7  */
    {0, SLCD_L6 },   /* PIN3  -> SCH_SLCDL2  -> PC10 -> L6  */
    {0, SLCD_L5 },   /* PIN4  -> SCH_SLCDL3  -> PC11 -> L5  */
    {0, SLCD_L4 },   /* PIN5  -> SCH_SLCDL4  -> PC12 -> L4  */
    {1, SLCD_L58},   /* PIN6  -> SCH_SLCDL5  -> PD6  -> L58 */
    {0, SLCD_L26},   /* PIN7  -> SCH_SLCDL6  -> PB1  -> L26 */
    {0, SLCD_L27},   /* PIN8  -> SCH_SLCDL7  -> PB0  -> L27 */
    {0, SLCD_L30},   /* PIN9  -> SCH_SLCDL8  -> PA7  -> L30 */

    {0, SLCD_L8 },   /* PIN16 -> SCH_SLCDL11 -> PD3  -> L8  */
    {0, SLCD_L9 },   /* PIN17 -> SCH_SLCDL12 -> PD2  -> L9  */
    {0, SLCD_L10},   /* PIN18 -> SCH_SLCDL13 -> PA12 -> L10 */
    {0, SLCD_L11},   /* PIN19 -> SCH_SLCDL14 -> PA11 -> L11 */
    {0, SLCD_L15},   /* PIN20 -> SCH_SLCDL15 -> PC9  -> L15 */
    {0, SLCD_L16},   /* PIN21 -> SCH_SLCDL16 -> PC8  -> L16 */
    {0, SLCD_L17},   /* PIN22 -> SCH_SLCDL17 -> PC7  -> L17 */

    {0, SLCD_L20},   /* PIN24 -> SCH_SLCDL19 -> PB14 -> L20 */
    {0, SLCD_L19},   /* PIN25 -> SCH_SLCDL20 -> PB15 -> L19 */
    {0, SLCD_L22},   /* PIN26 -> SCH_SLCDL21 -> PB12 -> L22 */
    {0, SLCD_L21},   /* PIN27 -> SCH_SLCDL22 -> PB13 -> L21 */
    {0, SLCD_L28},   /* PIN28 -> SCH_SLCDL23 -> PC5  -> L28 */
    {0, SLCD_L29},   /* PIN29 -> SCH_SLCDL24 -> PC4  -> L29 */
};
void LCD_Clear(void)
{
    SLCD->DR0  = 0;
    SLCD->DR1  = 0;
    SLCD->DR2  = 0;
    SLCD->DR3  = 0;
    SLCD->DR4  = 0;
    SLCD->DR5  = 0;
    SLCD->DR6  = 0;
    SLCD->DR7  = 0;
    SLCD->DR8  = 0;
    SLCD->DR9  = 0;
    SLCD->DR10 = 0;
    SLCD->DR11 = 0;
    SLCD->DR12 = 0;
    SLCD->DR13 = 0;
    SLCD->DR14 = 0;
    SLCD->DR15 = 0;
}
void LCD_WriteBit(u8 COMn, u32 Offset, u32 SEGn, u8 State)
{
    u8 Index = COMn * 2 + Offset;

    if(State) SLCD->RAM[Index] |=  SEGn;
    else      SLCD->RAM[Index] &= ~SEGn;
}
u8 LCD_SearchCode(char ch)
{
    u8 i;
    for(i = 0; i < 38; i++) {
        if(ch == LCD_CODE_Table[i].ch) {
            return LCD_CODE_Table[i].Data;
        }
    }

    return 0xFF;
}
void LCD_SearchName(char* str, u8* COMn, u8* SEGn)
{
    u8 i, j;
    for(i = 0; i < LCD_COM_NUMBER; i++) {
        for(j = 0; j < LCD_SEG_NUMBER; j++) {
            if(strcmp(str, LCD_NAME_Table[i][j]) == 0) {
                *COMn = i;
                *SEGn = j;
                return;
            }
        }
    }

    *COMn = 0xFF;
    *SEGn = 0xFF;
}
void LCD_DisplayNumber1(u8 Index, char ch, u8 Point)
{
    u8 i;
    char TAB[6][8][4] =  {
        {"5A ", "5B ", "5C ", "5D ", "5E ", "5F ", "5G ", "DP5"},
        {"6A ", "6B ", "6C ", "6D ", "6E ", "6F ", "6G ", "DP6"},
        {"7A ", "7B ", "7C ", "7D ", "7E ", "7F ", "7G ", "DP7"},
        {"8A ", "8B ", "8C ", "8D ", "8E ", "8F ", "8G ", "DP8"},
        {"9A ", "9B ", "9C ", "9D ", "9E ", "9F ", "9G ", "DP9"},
        {"10A", "10B", "10C", "10D", "10E", "10F", "10G", "   "},
    };

    u8 COMn = 0xFF, SEGn = 0xFF;

    u8 Code = LCD_SearchCode(ch);

    if(Code != 0xFF) {
        for(i = 0; i < 7; i++) {
            LCD_SearchName(TAB[Index][i], &COMn, &SEGn);

            if((COMn != 0xFF) && (SEGn != 0xFF)) {
                LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], (Code >> i) & 0x01);
            }
        }

        LCD_SearchName(TAB[Index][7], &COMn, &SEGn);

        if((COMn != 0xFF) && (SEGn != 0xFF)) {
            LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], Point);
        }
    }
}
void LCD_DisplayNumber2(u8 Index, char ch, u8 Point)
{
    u8 i;
    char TAB[4][8][4] = {
        {"1A ", "1B ", "1C ", "1D ", "1E ", "1F ", "1G ", "DP1"},
        {"2A ", "2B ", "2C ", "2D ", "2E ", "2F ", "2G ", "DP2"},
        {"3A ", "3B ", "3C ", "3D ", "3E ", "3F ", "3G ", "DP3"},
        {"4A ", "4B ", "4C ", "4D ", "4E ", "4F ", "4G ", "   "},
    };

    u8 COMn = 0xFF, SEGn = 0xFF;

    u8 Code = LCD_SearchCode(ch);

    if(Code != 0xFF) {
        for(i = 0; i < 7; i++) {
            LCD_SearchName(TAB[Index][i], &COMn, &SEGn);

            if((COMn != 0xFF) && (SEGn != 0xFF)) {
                LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], (Code >> i) & 0x01);
            }
        }

        LCD_SearchName(TAB[Index][7], &COMn, &SEGn);

        if((COMn != 0xFF) && (SEGn != 0xFF)) {
            LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], Point);
        }
    }
}
void LCD_DisplayUnit(u8 Index, u8 State)
{
    char TAB[10][4] = {"S1 ", "S2 ", "S3 ", "S4 ", "S9 ", "T1 ", "W1 ", "C1 ", "C2 ", "C3 "};

    u8 COMn = 0xFF, SEGn = 0xFF;

    LCD_SearchName(TAB[Index], &COMn, &SEGn);

    if((COMn != 0xFF) && (SEGn != 0xFF)) {
        LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], State);
    }
}

static u32 Number1  = 0;
static u32 Number2  = 0;
static u32 Counter  = 0;
static u32 Unit     = 0;
void LCD_DisplayDataUpdate(void)
{
    Number1 = (Number1 + 1) % 1000000;

    if(Number1 < 10) {
        LCD_DisplayNumber1(0, ' ', 0);
        LCD_DisplayNumber1(1, ' ', 0);
        LCD_DisplayNumber1(2, ' ', 0);
        LCD_DisplayNumber1(3, ' ', 0);
        LCD_DisplayNumber1(4, '0', 1);
        LCD_DisplayNumber1(5, '0' + Number1, 0);
    }
    else if(Number1 < 100) {
        LCD_DisplayNumber1(0, ' ', 0);
        LCD_DisplayNumber1(1, ' ', 0);
        LCD_DisplayNumber1(2, ' ', 0);
        LCD_DisplayNumber1(3, ' ', 0);
        LCD_DisplayNumber1(4, '0' + ((Number1 / 10) % 10), 1);
        LCD_DisplayNumber1(5, '0' + ((Number1 / 1 ) % 10), 0);
    }
    else if(Number1 < 1000) {
        LCD_DisplayNumber1(0, ' ', 0);
        LCD_DisplayNumber1(1, ' ', 0);
        LCD_DisplayNumber1(2, ' ', 0);
        LCD_DisplayNumber1(3, '0' + ((Number1 / 100) % 10), 0);
        LCD_DisplayNumber1(4, '0' + ((Number1 / 10 ) % 10), 1);
        LCD_DisplayNumber1(5, '0' + ((Number1 / 1  ) % 10), 0);
    }
    else if(Number1 < 10000) {
        LCD_DisplayNumber1(0, ' ', 0);
        LCD_DisplayNumber1(1, ' ', 0);
        LCD_DisplayNumber1(2, '0' + ((Number1 / 1000) % 10), 0);
        LCD_DisplayNumber1(3, '0' + ((Number1 / 100 ) % 10), 0);
        LCD_DisplayNumber1(4, '0' + ((Number1 / 10  ) % 10), 1);
        LCD_DisplayNumber1(5, '0' + ((Number1 / 1   ) % 10), 0);
    }
    else if(Number1 < 100000) {
        LCD_DisplayNumber1(0, ' ', 0);
        LCD_DisplayNumber1(1, '0' + ((Number1 / 10000) % 10), 0);
        LCD_DisplayNumber1(2, '0' + ((Number1 / 1000 ) % 10), 0);
        LCD_DisplayNumber1(3, '0' + ((Number1 / 100  ) % 10), 0);
        LCD_DisplayNumber1(4, '0' + ((Number1 / 10   ) % 10), 1);
        LCD_DisplayNumber1(5, '0' + ((Number1 / 1    ) % 10), 0);
    }
    else if(Number1 < 1000000) {
        LCD_DisplayNumber1(0, '0' + ((Number1 / 100000) % 10), 0);
        LCD_DisplayNumber1(1, '0' + ((Number1 / 10000 ) % 10), 0);
        LCD_DisplayNumber1(2, '0' + ((Number1 / 1000  ) % 10), 0);
        LCD_DisplayNumber1(3, '0' + ((Number1 / 100   ) % 10), 0);
        LCD_DisplayNumber1(4, '0' + ((Number1 / 10    ) % 10), 1);
        LCD_DisplayNumber1(5, '0' + ((Number1 / 1     ) % 10), 0);
    }

    Counter++;

    if((Counter % 100) == 0) {
        LCD_DisplayUnit(Unit, 0);

        Unit = (Unit + 1) % 10;

        LCD_DisplayUnit(Unit, 1);


        Number2 = (Number2 + 1) % 10000;

        if(Number2 < 10) {
            LCD_DisplayNumber2(0, ' ', 0);
            LCD_DisplayNumber2(1, ' ', 0);
            LCD_DisplayNumber2(2, ' ', 0);
            LCD_DisplayNumber2(3, '0' + Number2, 0);
        }
        else if(Number2 < 100) {
            LCD_DisplayNumber2(0, ' ', 0);
            LCD_DisplayNumber2(1, ' ', 0);
            LCD_DisplayNumber2(2, '0' + ((Number2 / 10) % 10), 0);
            LCD_DisplayNumber2(3, '0' + ((Number2 / 1 ) % 10), 0);
        }
        else if(Number2 < 1000) {
            LCD_DisplayNumber2(0, ' ', 0);
            LCD_DisplayNumber2(1, '0' + ((Number2 / 100) % 10), 0);
            LCD_DisplayNumber2(2, '0' + ((Number2 / 10 ) % 10), 0);
            LCD_DisplayNumber2(3, '0' + ((Number2 / 1  ) % 10), 0);
        }
        else if(Number2 < 10000) {
            LCD_DisplayNumber2(0, '0' + ((Number2 / 1000) % 10), 0);
            LCD_DisplayNumber2(1, '0' + ((Number2 / 100 ) % 10), 0);
            LCD_DisplayNumber2(2, '0' + ((Number2 / 10  ) % 10), 0);
            LCD_DisplayNumber2(3, '0' + ((Number2 / 1   ) % 10), 0);
        }
    }
}
#define USING_LSI_AS_SLCD_CLKSOURCE//USING_HSIDIV1SLCDDIV8_AS_SLCD_CLKSOURCE//USING_HSIDIV8SLCDDIV1_AS_SLCD_CLKSOURCE//USING_LSE_AS_SLCD_CLKSOURCE//

void slcd_init(void)
{
    u32 slcd_clk_source_freq;
    SLCD_InitTypeDef slcd_struct;

    SLCD_Prescaler_TypeDef pre_value = SLCD_Prescaler_1;
    SLCD_Divider_TypeDef   div_value = SLCD_Divider_16;

    RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_BKP, ENABLE);                            //Enabel BKP clock
    if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {
        RCC_BackupResetCmd(ENABLE);
        RCC_BackupResetCmd(DISABLE);
        PWR_BackupAccessCmd(ENABLE);
        RCC_LSEConfig(RCC_LSE_OFF);
    }
    else {
        PWR_BackupAccessCmd(ENABLE);                                            //allow BKP domain access
    }

    RCC_SLCD_ClockCmd(SLCD, ENABLE);                                            //LCD EN
    SLCD_DeInit();
#if defined(USING_HSIDIV1SLCDDIV8_AS_SLCD_CLKSOURCE)
    RCC_HSICLKConfig(RCC_HSI_ONDiv1);
    RCC_SLCDCLKConfig(RCC_SLCDCLKSource_HSI_Div8SLCD_Div1);                     //HSI DIV1 = 8M SLCD Div8 as LCD clock source
#elif defined(USING_HSIDIV8SLCDDIV1_AS_SLCD_CLKSOURCE)
    RCC_HSICLKConfig(RCC_HSI_ONDiv8);
    RCC_SLCDCLKConfig(RCC_SLCDCLKSource_HSI_Div1SLCD_Div8);                     //HSI DIV8 = 1M SLCD Div1 as LCD clock source
#elif defined(USING_LSE_AS_SLCD_CLKSOURCE)
    RCC_LSEConfig(RCC_LSE_ON);                                                  // Set LSE ON with crystal
    while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
    while(1) {
        RCC_SLCDCLKConfig(RCC_SLCDCLKSource_LSE);                               //LSE as LCD clock source
        if(RCC_GetSlcdClockConfig() == RCC_SLCDCLKSource_LSE) {
            break;
        }
    }
#elif defined(USING_LSI_AS_SLCD_CLKSOURCE)
    RCC_LSICLKConfig(RCC_LSICLKSource_40KHz);
    RCC_LSICmd(ENABLE);
    RCC_SLCDCLKConfig(RCC_SLCDCLKSource_LSI);                                   //LSI as LCD clock source
#else
#error "not define "
#endif

    //clock enabe for periphral
    RCC_GPIO_ClockCmd(GPIOA, ENABLE);
    RCC_GPIO_ClockCmd(GPIOB, ENABLE);
    RCC_GPIO_ClockCmd(GPIOC, ENABLE);
    RCC_GPIO_ClockCmd(GPIOD, ENABLE);

    slcd_clk_source_freq = RCC_GetSlcdClockFreq();
    if(slcd_clk_source_freq == 0) {
        //must check the clock source is on or not
        return;
    }
    else if(slcd_clk_source_freq <= (LSI_VALUE / 4)) {
        pre_value = SLCD_Prescaler_1;
        div_value = SLCD_Divider_16;
    }
    else if(slcd_clk_source_freq <= LSI_VALUE) {
        pre_value = SLCD_Prescaler_4;
        div_value = SLCD_Divider_16;
    }
    else if(slcd_clk_source_freq >= (HSI_VALUE) / 8) {
        pre_value = SLCD_Prescaler_32;
        div_value = SLCD_Divider_31;
    }

    SLCD_StructInit(&slcd_struct);
    slcd_struct.SLCD_Prescaler = pre_value;
    slcd_struct.SLCD_Divider = div_value;
    slcd_struct.SLCD_Duty = SLCD_Duty_1_4;
    slcd_struct.SLCD_Bias = SLCD_Bias_1_3;
    slcd_struct.SLCD_VoltageSource = SLCD_VoltSrcCapCharggDownVdd;
    SLCD_Init(&slcd_struct);
    SLCD_IO_Config(&(SEGorCOM[0]));                                             //must call after SLCD_init
    SLCD_COM_IndexInit(&(SCLD_COM_Index[0]));

    SLCD_ChargePumpClockDivConfig(SLCD_ChargePumpClock_Div1024);

    SLCD_LowPowerDriveCmd(DISABLE);
    SLCD_DeadTimeConfig(SLCD_DeadTime_0);

    LCD_Clear();

    SLCD_BlinkConfig(SLCD_BlinkMode_Off, SLCD_BlinkFrequency_Div512);
    SLCD_BLINK_IndexInit(SCLD_BLINK_Index);

    // Polling mode
    SLCD_Cmd(ENABLE);
}

void SystemInit (void);
////////////////////////////////////////////////////////////////////////////////
/// @brief  initialize LED GPIO pin
/// @note   if use jtag/swd interface GPIO PIN as LED, need to be careful,
///         can not debug or program.
/// @param  None.
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
void EnterStopWakeupbyExtiGPIO(void)
{
    //important notes
    //need to set those GPIO Pins as AIN exclude the wake up pin;
    //need to disalbe those interrupts (Systick, Timer), exclude the wake interrupt
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWREN, ENABLE);
    PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
    //After enter STOP mode, the SYSCLK changed to HSI/6
    //Need re-initialize the SYSCLK , set HSI/4+PLL to 48Mhz as SYSCLK
    SystemInit();
    //re-initialize those GPIO Pins as previous setting before the wake up pin;
    //re-enalbe those interrupts (Systick, Timer) as previous setting before
    //the wake up pin

}

void slcd_test(void)
{
    u16 i = 0;

    slcd_init();

    while(1) {
        LCD_DisplayDataUpdate();
#if defined(USING_HSIDIV8SLCDDIV1_AS_SLCD_CLKSOURCE)
        DELAY_Ms(10);
#else
        DELAY_Ms(100);
#endif
        i++;
        if(i == 100) {
            break;
        }
    }
    //important note: used stop display LCD , only can select LSE and LSI as SLCD clock source
    //can not select HSI Div1 or Div8 as SLCD clock source, because HSI is off when enter STOP
    EnterStopWakeupbyExtiGPIO();
    while(1) {
        LCD_DisplayDataUpdate();
#if defined(USING_HSIDIV8SLCDDIV1_AS_SLCD_CLKSOURCE)
        DELAY_Ms(10);
#else
        DELAY_Ms(100);
#endif
    }
}

